﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
//using ESYSShell;
using System.IO;

namespace try_dll
{
    public partial class Form1 : Form
    {
        private string str_project_name = "entrynav";
        private string str_esys_path = "D:\\EC-Apps";
        private string str_esys_data_path = "D:\\ESYS";
        private string str_pdx_path = "D:\\temp\\tmp_entry\\A12464A";
        private string str_fa_path = "D:\\ESYS\\FA\\ASE83031_black_535_Shanghai_with_tpeg.xml";
        private string str_tal_name = "";
        private Hashtable tbl_tal = new Hashtable();
        private ArrayList  array_tal = new ArrayList();
        private string app_dir;
        private Config icfg = new Config();

        private enum cfg_items_enum { 
            PROJECT_NAME,
            ESYS_DIR,
            ESYS_DATA_DIR,
            RELEASE_DIR,
            FA_FILE_PATH,
            TAL_FILE_NAME
        }
        private class Config { 
            //public string esys_dir;
            //public string esys_dir;
            //public string release_dir;
            //public string FA_dir;
            public string cfg_file_full_path;
            public Hashtable tbl_cfg;

            public Config() {
                this.cfg_file_full_path = Directory.GetCurrentDirectory() + "\\"+"MMI_CFG.cfg";
                this.tbl_cfg = new Hashtable();
                //this.tbl_cfg.Add("PROJECT_NAME", "ENTRY_NAV/MEDIA");
            }
            public string load_cfg_file() { 
                  try
                {
                    //log_handle.log_info("i", "start to read config file: [" + config_path + "]");
                    using (StreamReader sr = new StreamReader(this.cfg_file_full_path))
                    {
                        string line;
                        while (true )
                        {
                            line = sr.ReadLine();
                            if (line != null && line != "")
                            {
                                if (!line.Contains('#'))
                                {
                                    string[] temp_config_info_list = line.Split('=');
                                    this.change_item(temp_config_info_list[0].Replace(" ", ""), temp_config_info_list[1].Replace(" ", ""));
                                }
                                else
                                {
                                    //log_handle.log_info("i", "skip line due to # occurs: \n" + line);
                                    continue;
                                }
                            }
                            else {
                                break;
                            }
                        }
                        sr.Close();
                    }
                }
                catch (Exception e) {
                    //log_handle.log_info("e", "read config file error: [" + e.Message + "]");
                    return e.Message;
                }
                  if (this.tbl_cfg.Keys.Count < 5)
                  {
                      return "Miss info of some settings in config file.";
                  }
                  else {
                      return "";
                  }
            }
            public string write_new_cfg()
            {
                if (File.Exists(this.cfg_file_full_path))
                {
                    try
                    {
                        File.Delete(this.cfg_file_full_path);
                        File.Create(this.cfg_file_full_path).Close();
                    }
                    catch (Exception e)
                    {
                        //log_handle.log_info("e", "Error while create new config file: [" + e.Message + "]");
                        return e.Message;
                    }
                }
                try
                {
                    using (StreamWriter sw = new StreamWriter(this.cfg_file_full_path))
                    {
                        foreach (DictionaryEntry de in this.tbl_cfg)
                        {
                            sw.WriteLine(de.Key.ToString() + " = " + de.Value.ToString());
                        }
                        sw.Close();
                    }
                }
                catch (Exception e)
                {
                    //log_handle.log_info("e", "error while write new config content: [" + e.Message + "]");
                    return e.Message;
                }
                return "";
            }
            public void change_item(string key, string value)
            {
                if (this.tbl_cfg.ContainsKey(key))
                {
                    this.tbl_cfg[key] = value;
                }
                else
                {
                    this.tbl_cfg.Add(key, value);
                }

            }
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void button_flash_Click(object sender, EventArgs e)
        {
            string dll_path = this.app_dir + "\\ESYSShell.dll";
            
            int step = 0;
            int result = 0;

            // update display info and log the current configurations.
            this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.PROJECT_NAME).ToString(), "ENTRY_NAV/MEDIA");
            this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.TAL_FILE_NAME).ToString(), this.cbb_tal_file.SelectedItem.ToString());
            this.update_var();
            this.str_tal_name = this.tbl_tal[this.cbb_tal_file.SelectedItem.ToString()].ToString();
            string[] paras = new string [] {str_project_name, str_esys_path, str_esys_data_path, str_pdx_path, str_fa_path,str_tal_name};

            Cursor.Current = Cursors.WaitCursor;

            this.icfg.write_new_cfg();
            this.update_status_display("now we are flashing using esys bat...");
            // load dll file.
            try
            {
                Assembly ESYSShell = Assembly.LoadFrom(dll_path);
                Type shell = ESYSShell.GetType("ESYSShell.Shell");
                //Type shell = ESYSShell.GetType("ESYSShell.Shell");
                object iShell = Activator.CreateInstance(shell, paras);
                MethodInfo iShell_OneClickFlash = shell.GetMethod("one_click_flash");
                result = (int)iShell_OneClickFlash.Invoke(iShell, new object[] { step });
            }
            catch (Exception ee)
            {
                this.update_status_display("Error happened while calling ESYSShell.dll.");
                MessageBox.Show(ee.Message);
            }


            //this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.PROJECT_NAME).ToString(), "ENTRY_NAV/MEDIA");
            //this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.TAL_FILE_NAME).ToString(), this.cbb_tal_file.SelectedItem.ToString());
            ////this.str_tal_name = this.tbl_tal[this.cbb_tal_file.SelectedItem.ToString()].ToString();
            //Shell test = new Shell(str_project_name, str_esys_path, str_esys_data_path, str_pdx_path, str_fa_path, this.str_tal_name);
            //this.update_status_display("now we are flashing using esys bat...");
            //result = test.one_click_flash();
            Cursor.Current = Cursors.Default;
            if (result != 0) {
                switch (result) { 
                    case 5:
                        this.update_status_display("Error while delete old pdx data in esys data folder.");
                        break;
                    case 4:
                        this.update_status_display("Error while auto locate pdx file and tal file.");
                        break;
                    case 3:
                        this.update_status_display("Error wihle copy temp files for esys.");
                        break;
                    case 2:
                        this.update_status_display("Error while execute pdx import.");
                        break;
                    case 1:
                        this.update_status_display("Error while execute tal execution.");
                        break;
                    case 0:
                        this.update_status_display("flash target using esys bat succeeded.");
                        break;
                    default:
                        this.update_status_display("unexpected error happened.");
                        break;
                }
            }
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string exec_results;
            Application.ApplicationExit += new EventHandler(this.before_close);

            this.app_dir = Directory.GetCurrentDirectory();
            exec_results = icfg.load_cfg_file();
            if (exec_results != "")
            {
                MessageBox.Show(exec_results,"Warning");
            }
            else {

                this.update_mmi();
            }
        }

        private void before_close(Object sender, EventArgs e)
        {
            this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.PROJECT_NAME).ToString(), "ENTRY_NAV/MEDIA");
            this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.TAL_FILE_NAME).ToString(), this.cbb_tal_file.SelectedItem.ToString());
            this.icfg.write_new_cfg();
        }

        private void update_mmi(){
            //this.tb_esys.Text = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), 0).ToString()].ToString();
            this.tb_project.Text = this.icfg.tbl_cfg["PROJECT_NAME"].ToString();
            this.tb_esys.Text = this.icfg.tbl_cfg["ESYS_DIR"].ToString();
            this.tb_esys_data.Text = this.icfg.tbl_cfg["ESYS_DATA_DIR"].ToString();
            this.tb_release.Text = this.icfg.tbl_cfg["RELEASE_DIR"].ToString();
            this.tb_change_fa.Text = this.icfg.tbl_cfg["FA_FILE_PATH"].ToString();
            this.update_status_display("mmi info updated");
        }
        private void update_var() {
            this.str_project_name = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.PROJECT_NAME).ToString()].ToString();
            this.str_esys_path = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DIR).ToString()].ToString();
            this.str_esys_data_path = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DATA_DIR).ToString()].ToString();
            this.str_pdx_path = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.RELEASE_DIR).ToString()].ToString();
            this.str_fa_path = this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.FA_FILE_PATH).ToString()].ToString();
        
        }
        private void update_status_display(string status) { 
            string now = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            this.label_status.Text = now + ": " + "\t" + status;
            this.label_status.Refresh();
        }

        private void button_change_esys_Click(object sender, EventArgs e)
        {
            string esys_dir;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                esys_dir = folderBrowserDialog1.SelectedPath;
            }
            else {
                return;
            }
               //this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DIR).ToString()] =
               this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DIR).ToString(), esys_dir);
               this.tb_esys.Text = esys_dir;
               this.update_status_display("esys dir changed.");
               //this.icfg.write_new_cfg();
        }

        private void button_change_esys_data_Click(object sender, EventArgs e)
        {
            string esys_data_dir;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                esys_data_dir = folderBrowserDialog1.SelectedPath;
            }
            else {
                return;
            }
               //this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DIR).ToString()] =
               this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DATA_DIR).ToString(), esys_data_dir);
               this.tb_esys_data.Text = esys_data_dir;
               this.update_status_display("esys data dir changed");
               //this.icfg.write_new_cfg();
        }

        private void button_change_release_Click(object sender, EventArgs e)
        {
            string release_dir;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                release_dir = folderBrowserDialog1.SelectedPath;
            }
            else {
                return;
            }
               //this.icfg.tbl_cfg[Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.ESYS_DIR).ToString()] =
               this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.RELEASE_DIR).ToString(), release_dir);
               this.tb_release.Text = release_dir;
               this.update_status_display("release dir changed.");
               //this.icfg.write_new_cfg();

            //next we need to search over the pdx folder and get all the tal file
            DirectoryInfo rel_di = new DirectoryInfo(release_dir);
            this.get_folder_4_tal(rel_di);

            foreach (FileInfo s  in this.array_tal) {
                this.cbb_tal_file.Items.Add(s.Name);
            }
            
            }

        private void button_change_fa_Click(object sender, EventArgs e)
        {
            string fa_file_path;
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                fa_file_path = this.openFileDialog1.FileName;
            }
            else {
                return;
            }
            this.icfg.change_item(Enum.GetName(typeof(cfg_items_enum), cfg_items_enum.FA_FILE_PATH).ToString(), fa_file_path);
            this.tb_change_fa.Text = fa_file_path;
            this.update_status_display("fa file path changed.");
            //this.icfg.write_new_cfg();
        }

        private void search_tal_file(DirectoryInfo dir) {
            foreach (FileInfo tmp_tal_fi in dir.GetFiles()) {
                if (tmp_tal_fi.Name.Contains("TAL") && tmp_tal_fi.Name.Contains("xml")) {
                    this.array_tal.Add(tmp_tal_fi);
                    this.tbl_tal.Add(tmp_tal_fi.Name, tmp_tal_fi.FullName);
                }
            }
        }
        private void get_folder_4_tal(DirectoryInfo dir) {
            this.search_tal_file(dir);
            foreach (DirectoryInfo di in dir.GetDirectories()) {
                this.get_folder_4_tal(di);
            }
        }

    }
}
